package com.easymin.weixin.filters;

import com.easymin.weixin.ValidateToken;
import com.easymin.weixin.common.IpHelper;
import com.easymin.weixin.common.geetest.GeetestLib;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 增加验证码判断.
 *
 * @author Shine
 */
public class AuthenticationFilter extends FormAuthenticationFilter {
  
  private static final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);

  @Override
  protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {

    String username = getUsername(request);
    String password = getPassword(request);
    boolean rememberMe = isRememberMe(request);
    String host = getHost(request);

    HttpServletRequest localRequest = (HttpServletRequest) request;

    String ip = IpHelper.getIp(localRequest);

    // 验证码
    GeetestLib geetest = GeetestLib.getGtSession(localRequest);
    int gtServerStatusCode = GeetestLib.getGtServerStatusSession(localRequest);

    String gtResult = "fail";

    if (gtServerStatusCode == 1) {
      gtResult = geetest.enhencedValidateRequest(localRequest);
    } else {
      gtResult = geetest.failbackValidateRequest(localRequest);
    }

    if (!GeetestLib.success_res.equals(gtResult)) {
      throw new UnsupportedTokenException();
    }

    return new ValidateToken(username, password.toCharArray(), rememberMe, host, ip);
  }

  @Override
  protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
      throws Exception {

    HttpServletRequest localHttpServletRequest = (HttpServletRequest) request;

    HttpServletResponse localHttpServletResponse = (HttpServletResponse) response;

    String str = localHttpServletRequest.getHeader("X-Requested-With");

    if ((str != null) && (str.equalsIgnoreCase("XMLHttpRequest"))) {
      localHttpServletResponse.addHeader("loginStatus", "accessDenied");
      localHttpServletResponse.sendError(403);
      return false;
    }

    return super.onAccessDenied(request, response);
  }

  @Override
  protected boolean executeLogin(
      ServletRequest request, ServletResponse response) throws Exception {

    AuthenticationToken token = createToken(request, response);

    if (token == null) {
      String msg =
          "createToken method implementation returned null. A valid non-null AuthenticationToken "
              + "must be created in order to execute a login attempt.";
      throw new IllegalStateException(msg);
    }
    try {
      Subject subject = getSubject(request, response);
      subject.login(token);
      return onLoginSuccess(token, subject, request, response);
    } catch (AuthenticationException ex) {
      logger.error(ex.getMessage());
      return onLoginFailure(token, ex, request, response);
    }

  }

}
